import re
import copy
import numpy as np
import os
from commanded.Config import Config
from commanded.Searcher import Searcher
from ViewControler import *


class WinData:

    def __init__(self):
        self.rootPath = None  # 运行路径
        self.exclList = None  # 支持查询的EXCEL列表
        self.blackPanel = None  # 主题模式
        self.highColor = None  # 高亮颜色值
        self.highSize = None  # 字体大小
        self.histryPath = None  # 历史路径
        self.config = None  # config对象
        self.SSelect = None  # 默认Excel表格
        self.SExclPath = None  # 默认路径
        self.SBaseEdit = None  # 单表查询输入框文本
        self.SResourceEdit = None  # 活动查询-规划输入框文本
        self.STargetEdit = None  # 活动查询-基础表输入框文本
        self.SDataRadioButton = True  # 规划查询单选按钮
        self.P7DataRadioButton = False  # P7规划查询单选按钮
        self.SStrRadioButton = False  # 纯文本比对单选按钮
        self.SGoDataCheckBox = False  # 详情弹窗复选按钮
        self.SCostsComboBox = None  # 限购和折扣下拉框
        self.reTitleDic = None  # 比对源数据下标字典
        self.taTitleDic = None  # 比对目标数据下标字典
        self.searcher = None  # 查询控制器对象
        self.openDialog = None  # 弹窗控件对象
        self.colorKey = 0  # 是否标志存在差异
        self.reAllInfo = []  # 规划查询详细信息列表
        self.taAllInfo = []  # 基础表查询详细信息列表
        self.reDiffInfo = []  # 规划差异信息列表
        self.taDiffInfo = []  # 基础表差异信息列表
        self.diffIndex = []  # 差异行数坐标
        self.TExclList = None
        self.TSelect = None
        self.TList = None
        self.SRGLabel = None  # 查询页面大Label控件对象
        self.lableView = LableView()
        self.SetData()

    def GetSAE(self, text, dataNumber=0):
        """
        根据数据来源解析数据\n
        :param text: 需要解析的内容
        :param dataNumber: 数据来源编码，0为规划表内容，1为基础表内容
        :return: 规划表=>提取出reward格式数据列表（二维列表），costs格式数据列表（二维列表）;
        基础表=>提取出reward格式数据列表（二维列表），costs格式数据列表（二维列表），品类编码列表
        """
        pattern1 = "-?\d+\,-?\d+\,-?\d+"

        def GetReLineValue(strList, valueType=0):
            """
            通过字段下标获取列表对应下标的值\n
            :param strList: 通过空格分割的字符串列表
            :param valueType: 规划数据字典的检索类型：1 = costs, 0 = rewards
            :return:返回对应类型检索出来的下标的值
            """
            indexType = 'rewards'
            if valueType != 0:
                indexType = 'costs'
            str_length = len(strList)
            tempList = []
            for xList in self.reTitleDic[indexType]:
                x = xList[0]
                y = xList[1]
                if x >= str_length or y >= str_length:
                    break
                tempList.append([strList[x], strList[y]])
            return tempList

        def getResource():
            dataList = []
            costList = []
            # strList = []
            # numberList = set()
            pattern_t = '\t'
            if pattern_t in text:
                # 如果有制表符，将制表符替换成 空格
                mytext = text.replace(pattern_t, ' ').strip()
            else:
                # mytext = text.replace(' ', ',')  # 如果有空格将空格替换成 ， 号
                mytext = text.strip()

            objList = mytext.splitlines()  # 将字符串按行分割成行列表
            objList.pop(0)  # 删除第一行（行头：道具1 编号 数量 商品输出 消耗1 编号 数量 ...）

            if len(objList) > 0:
                for item in objList:
                    # 将单行按空格分割成数据列表 演示：
                    # ['红元神碎片自选箱', '11,20177', '20', '[[11,20177,20]]', '端', '11,800029', '20', '1400'...]
                    strtemp = item.split()
                    # 将提取的结果添加到data列表 提取数据演示：[['红元神碎片自选箱', '20']]
                    dataList.append(GetReLineValue(strtemp))
                    # 判断是否需要比对消耗
                    if self.SCostsComboBox:
                        # 将提取的结果添加到cost列表 提取数据演示：[['端', '20'], ['午', '20']...]
                        costList.append(GetReLineValue(strtemp, 1))

            return dataList, costList

        def getTarget():
            dataList = []
            costList = []
            dataTempList = []
            costTempList = []
            numberList = set()
            pattern_t = '\t'

            if pattern_t in text:
                mytext = text.replace('\t', ' ').strip()
            else:
                mytext = text.strip()
            # 通过行分割成列表，格式：['[[11,800029,20],[11,800030,20],[11,800031,20],[11,800032,20]] [[11,20177,20]]',...]
            objList = mytext.splitlines()
            # 删掉首行（行头：costs rewards）
            objList.pop(0)

            if len(objList) > 0:
                for item in objList:
                    if item:
                        # 将每一行通过空格将 costs对应的数据和 rewards对应的数据 提取成列表
                        # 格式：['[[11,800029,20],[11,800030,20],[11,800031,20],[11,800032,20]]', '[[11,20177,20]]']
                        strtemp = item.split()
                        # 匹配多个reward格式字符串 演示：['11,20177,20']
                        rewardsStr = re.findall(pattern1, strtemp[self.taTitleDic['rewards']])
                        if len(rewardsStr) > 0:
                            for data in rewardsStr:  # 格式：'11,20177,20'
                                strList = data.strip().split(',')  # 通过逗号分割成单个reward内容列表 演示：['11', '20177', '20']
                                numberList.add(strList[0])  # 添加品类编码
                                dataTempList.append(strList)  # 添加单个奖励
                        if self.SCostsComboBox:
                            # 匹配多个costs格式字符串 演示：['11,800029,20', '11,800030,20', '11,800031,20', '11,800032,20']
                            costsStr = re.findall(pattern1, strtemp[self.taTitleDic['costs']])
                            if len(costsStr) > 0:
                                for data in costsStr:
                                    # 通过逗号分割成单个costs内容列表 演示：['11', '800030', '20']
                                    strList = data.strip().split(',')
                                    numberList.add(strList[0])  # 添加品类编码
                                    costTempList.append(strList)  # 添加单个奖励
                        dataList.append(copy.deepcopy(dataTempList))
                        costList.append(copy.deepcopy(costTempList))
                        dataTempList.clear()
                        costTempList.clear()

                return dataList, costList, numberList

        if dataNumber == 0:  # 如果是规划表
            return getResource()
        elif dataNumber == 1:  # 如果是基础表
            return getTarget()

    @staticmethod
    def Lev_distance(resour, target):
        """
        获取字符串最短编辑距离（如果有一个字符存在差异，则编辑距离为1，以此类推，差异越大，编辑距离就越大）
        :param resour: 源数据
        :param target: 目标数据
        :return: 返回两组字符串之间的最短编辑距离
        """
        bArray = np.array(np.arange(len(target) + 1))  # 创建1维数组，长度比B多1
        for i in range(1, len(resour) + 1):
            temp1 = bArray[0]
            bArray[0] += 1
            for j in range(1, len(target) + 1):
                temp2 = bArray[j]
                if resour[i - 1] == target[j - 1]:
                    bArray[j] = temp1
                else:
                    bArray[j] = min(temp1, min(bArray[j - 1], bArray[j])) + 1
                temp1 = temp2
        return bArray[len(target)]

    @staticmethod
    def GetDataForLev(resour, target):
        """
        通过最短编辑距离，获取两组字符串之间的差异化数据\n
        :param resour: 源数据
        :param target: 目标数据
        :return: 返回最短编辑距离，字符串之间的长度偏移量，差异化字符量
        """
        _offset = len(target) - len(resour)
        _lev = WinData.Lev_distance(resour, target)
        _diffCount = _lev - _offset
        return _lev, _offset, _diffCount

    @staticmethod
    def FindDiffFirst(resour, target):
        """
        查找第一个不相同的位置下标\n
        :param resour: 源数据
        :param target: 目标数据
        :return: 返回第一个差异字符的下标
        """
        length_r = len(resour)
        length_t = len(target)
        for i in range(length_r):
            if resour[i] != target[i]:
                return i
        if length_r < length_t:
            return length_r + 1

    @staticmethod
    def FindDiffAll(resour, target):
        """
        查找所有不同位置的下标\n
        :param resour: 源数据
        :param target: 目标数据
        :return: 返回第所有差异字符的下标
        """
        length_r = len(resour)
        length_t = len(target)
        indexList = []
        for i in range(length_r):
            if resour[i] != target[i]:
                indexList.append(i)
        if length_r < length_t:
            offset = length_t - length_r
            for x in range(offset):
                indexList.append(length_r + x)
        return indexList

    @staticmethod
    def GetList(myList):
        """
        将二维数组解析为一维列表\n
        :param myList: 需要解压的二维列表，必须是二维的
        :return: 返回一个解压后的有序一维列表
        """
        tempList = []
        for items in myList:
            for item in items:
                tempList.append(item)
        return tempList

    def SetData(self):
        """
        读取配置，并设置窗口数据
        """
        self.config = config = Config()
        isOK = config.SetDefault()
        if isOK:
            self.rootPath = config.rootPath
            self.exclList = config.exclList
            self.blackPanel = config.blackPanel
            self.highColor = config.highColor
            self.highSize = config.highSize
            self.SSelect = config.searchSelect
            self.SExclPath = config.searchExclPath
            self.TExclList = config.tacticsExclList
            self.TSelect = config.tacticsSelect
            self.TList = config.tacticsList
            self.histryPath = config.histryPath
            self.SetSearcher()
            self.openDialog = OpenDialog()
        else:
            self.openDialog = OpenDialog()
            self.openDialog.ShowMessage(''.join(config.eInfo))
            os.startfile(self.config.readerConfigPath)

    def SetSearcher(self):
        self.searcher = Searcher(self.config.searchExclPath, self.config.itemType)

    def IsEqual(self):
        """
        比对两组数据中的字符串是否相同\n
        :return: 相等返回 True
        """
        resource, target = self.SResourceEdit.strip(), self.STargetEdit.strip()
        if len(resource) != len(target):
            return False

        if resource == target:
            return True
        else:
            return False

    def GetSBE(self):
        """
        解析搜索内容文本并以元组的形式返回，元组头部指定内容为数字或者中文\n
        :return: 返回解析后的搜索列表
        """
        tempList = []
        # 在列表开头添加搜索ID的文字类型
        result = re.search("^[1-9]\d*", self.SBaseEdit)
        if result:
            tempList.append("1")  # 数字为1
        else:
            tempList.append("0")  # 中文为0
        # 选择使用的逗号
        if ',' in self.SBaseEdit:
            temp = ','
        elif '，' in self.SBaseEdit:
            temp = '，'
        else:
            # 没有逗号的直接返回
            tempList.append(self.SBaseEdit)
            return tuple(tempList)
        # 查询的内容分割后去除空格和空
        for item in self.SBaseEdit.split(temp):
            if item:
                tempList.append(item.strip())
        return tuple(tempList)

    def ShowAllInfo(self, showType=0):
        if not self.SResourceEdit or not self.STargetEdit:
            self.openDialog.ShowMessage("无可展示内容！！！")
            return
        for x in range(len(self.taAllInfo)):
            self.taAllInfo[x] = str(self.taAllInfo[x]).replace("'", "").replace('"', "")
        showDatalog = ShowDatalog()
        reTextList = copy.deepcopy(self.SResourceEdit.splitlines())
        if showType == 0:
            reTextList.pop(0)
        if showType == 1:
            ...
        reText = '<br />'.join(reTextList)
        taText = '<br />'.join(self.taAllInfo)

        showDatalog.AddRedText(showDatalog.datalog.resourceEdit, reText)
        showDatalog.AddRedText(showDatalog.datalog.targetEdit, taText)
        showDatalog.ShowDialog()

    def GetSameLengthDiff(self, resour, target):
        """
        获取相同长度时的差异化展示数据\n
        :param resour: 源数据
        :param target: 目标数据
        :return: 返回标记后的差异化数据列表
        """
        indexList = WinData.FindDiffAll(resour, target)
        _relist = list(resour)
        _talist = list(target)
        for i in range(len(resour)):
            if i in indexList:
                _relist[i], _talist[i] = self.MarkT(_relist[i]), self.MarkT(_talist[i])
        return _relist, _talist

    def GetDiffLengthDiff(self, resour, target):

        def GetDiff(_reList, _taList):
            # 获取首次比对数据结果
            myLev, myOffSet, myDiffCount = WinData.GetDataForLev(_reList, _taList)
            # 初始化临时列表
            reTempList = copy.deepcopy(_reList)
            # 获取所有差异位置下标
            allDiffIndex = WinData.FindDiffAll(_reList, _taList)
            allLength = len(allDiffIndex)
            for i in range(allLength):
                diffI = allDiffIndex[i]
                # 将目标字符串相同位置的字符插入到比对源字符串中
                if _taList[diffI] == '[':
                    reTempList.insert(diffI, ' ')
                elif _taList[diffI] == ']':
                    reTempList.insert(diffI, ' ')
                else:
                    reTempList.insert(diffI, _taList[diffI])
                # 获取插值后的比对数据结果
                newLev, newOffset, newDiffCount = WinData.GetDataForLev(reTempList, _taList)
                # 新的编辑距离如果比旧大，说明插入位置不对
                if newLev > myLev:
                    # 初始化临时列表
                    reTempList.clear()
                    reTempList = copy.deepcopy(_reList)
                # 新编辑距离如果小于或者等于旧的
                else:
                    # 还需要判断差异量，如果新差异量大于旧差异量，说明位置还是不正确
                    if newDiffCount > myDiffCount:
                        # 初始化临时列表
                        reTempList.clear()
                        reTempList = copy.deepcopy(_reList)
                    # 只有新编辑距离小于等于，且新差异量小于等于旧数据时，才算正确
                    else:
                        # 将正确的下标添加到正确下标列表中
                        offsetIndex.append(diffI)
                        return list(reTempList), newOffset

        ######################################################################
        reverse = False
        reList, taList = [], []
        if len(resour) > len(target):
            reList, taList = list(target), list(resour)
            reverse = True
        elif len(resour) < len(target):
            reList, taList = list(resour), list(target)
        elif len(resour) == len(target):
            reList, taList = self.GetSameLengthDiff(resour, target)
            return reList, taList
        # 初始化一个储存正确插值下标的数组
        offsetIndex = []
        # 获取首次比对数据结果
        lev, offset, diffCount = WinData.GetDataForLev(reList, taList)
        newList = copy.deepcopy(reList)
        # 循环进行插值，找到正确插值下标，当返回的偏移量为0时，说明插值都已经正确
        try:
            while offset != 0:
                newList, offset = GetDiff(newList, taList)
        except TypeError as e:
            log.Show(e, 40)
            log.Show(f'{newList}', 40, 'GetDiffLengthDiff():newList')
            log.Show(f'{offset}', 40, 'GetDiffLengthDiff():offset')

        # 经过插值部位后，短字符串长度和长字符串相同，这时再为差异部分做标记
        newList, taList = self.GetSameLengthDiff(newList, taList)
        # 将短字符串插值的下标记录下来，逆向排列，后面需要按照这个插值下标将插值去除
        offsetIndex = offsetIndex[::-1]
        # log.Show(f'{newList}', 30, 'newList')
        # log.Show(offsetIndex, 30, "offsetIndex ")
        # 通过逆向坐标去除插值，还原字符串
        reList = copy.deepcopy(newList)
        for index in offsetIndex:
            del reList[index]
            taList[index] = self.MarkT(taList[index])

        # 如若反转字符串标记为真，则将源字符串和目标字符串反转
        if reverse:
            reList, taList = taList, reList
        return reList, taList

    def SetDifferentInfo(self, resource, targer):
        """
        处理差异化字符串内容，并添加到展示信息内容中\n
        :param resource: 源字符串
        :param targer: 目标字符串
        """

        def AddDifferent(myre, myta):
            resourceInfo, targetInfo = self.GetDiffLengthDiff(myre, myta)
            self.reAllInfo.append(f"{''.join(resourceInfo)}")
            self.taAllInfo.append(f"{''.join(targetInfo)}")
            self.reDiffInfo.append(f"{''.join(resourceInfo)}")
            self.taDiffInfo.append(f"{''.join(targetInfo)}")

        relist = resource.splitlines()
        talist = targer.splitlines()
        rel = len(relist)
        tal = len(talist)
        length = rel
        offset = 0
        key = True

        if rel > tal:
            length = tal
            offset = rel - tal
            key = True
        elif rel < tal:
            length = rel
            offset = tal - rel
            key = False

        for i in range(length):
            reline, taline = relist[i].strip(), talist[i].strip()
            # 先判断字符串长度是否【不一致】,内容部分存在空格也属于不一致
            if len(reline) != len(taline):
                AddDifferent(reline, taline)
            else:
                # 如果长度一致，在简单判断字符串整体是否【不一致】
                if reline != taline:
                    AddDifferent(reline, taline)
                else:
                    # 如果整体内容一致，那么就肯定一致了
                    self.reAllInfo.append(f"{reline}")
                    self.taAllInfo.append(f"{taline}")

        if offset > 0:
            for i in range(offset):
                if key:
                    self.reAllInfo.append(
                        f"{self.MarkT(f'倒数第 {i + 1} 行 多出来了！')}<br /> {self.MarkT(relist[-i])}<br />")
                else:
                    self.taAllInfo.append(
                        f"{self.MarkT(f'倒数第第 {i + 1} 行 多出来了！')}<br /> {self.MarkT(talist[-i])}<br />")

    def SetSameInfo(self, resource, targer):
        """
        设置相同内容比对详情\n
        :param resource: 比对源字符串
        :param targer: 比对目标字符串
        """
        self.reAllInfo.append(f"{resource}<br />")
        self.taAllInfo.append(f"{targer}<br />")

    def MarkT(self, text):
        """
        为差异内容添加标记\n
        :param text: 需要标记的差异化内容
        :return: 返回做了标记后的字符串
        """
        return f'<font color="{self.highColor}" size="{self.highSize}">{text}</font>'

    def GetDifferent(self, resource, target):
        def FirstCheck():
            resoultlist = []
            xyindex = []
            for x in range(rel):
                # print(x,'----------------------------------------------------')
                # print('x=>',x ,reList[x],taList[x])
                # 判断相同位置的字符是否一致
                if reList[x] == taList[x]:
                    # print(f"x=>{x} ({reList[x]}=={taList[x]}) [{x},{x}]")
                    xyindex.append(x)
                    resoultlist.append(reList[x])
                else:
                    firstKey = True
                    # 从X+1位开始循环
                    for y in range(x + 1, tal):
                        # print('y=>',y ,reList[x],taList[y])
                        # 判断目标字符是否和源字符存在相同字符
                        if reList[x] == taList[y]:
                            # print(f"x=>{x} y=>{y}({reList[x]}=={taList[y]}) [{x},{y}]")
                            # 存下相同字符，则退出二次循环
                            xyindex.append(y)
                            resoultlist.append(reList[x])
                            firstKey = False
                            break

                    if firstKey:
                        # 循环结束后如果未出现相同字符，则下标为-1
                        resoultlist.append(self.MarkT(reList[x]))

            return resoultlist, xyindex

        def NextCheck(indexlist):
            resoultlist2 = []
            for y in range(tal):
                if y in indexlist:
                    resoultlist2.append(taList[y])
                else:
                    resoultlist2.append(self.MarkT(taList[y]))
            return resoultlist2

        ####################################################################
        if len(resource) > len(target):
            reList = list(target)
            taList = list(resource)
            key = True
        else:
            reList = list(resource)
            taList = list(target)
            key = False

        rel = len(reList)
        tal = len(taList)

        resoult1, myindex = FirstCheck()
        resoult2 = NextCheck(myindex)

        if key:
            resoult1, resoult2 = resoult2, resoult1
        return ''.join(resoult1), ''.join(resoult2)

    def StrCheck(self):
        """
        文本比对，并设置展示内容,返回true表示操作成功
        """
        # 判断两个框中的文本是否相同（长度相同，内容相同）
        if self.IsEqual():  # 如果相同
            # 设置相同时展示的详细内容
            self.SetSameInfo('<br />'.join(self.SResourceEdit.splitlines()),
                             '<br />'.join(self.STargetEdit.splitlines()))
            return True
        else:  # 如果不同
            # 设置差异化展示标记
            self.colorKey = 1
            # 处理差异化字符串内容，并添加到展示信息内容中
            self.SetDifferentInfo(self.SResourceEdit, self.STargetEdit)
            return False

    def GetActivityData(self, taRewards: list):
        # 解析基础表列表
        # 通过ID获取缓存中的道具名称
        # 将名称添加到列表中
        # 返回整合好的数据

        ...

    def CheckData(self):
        """
        检查规划数据，设置WINDATA差异信息，以及主面板差异部分信息\n
        :return: 返回主面板展示差异部分信息
        """
        searcher = self.searcher
        dirPath = self.SExclPath

        def CheckContents(reList, taList):
            """
            将基础表和规划进行校验\n
            :param reList: 规划字符串列表
            :param taList: 基础表字符串列表
            :return: 返回检查后的基础表列表，如果存在问题，会将问题进行标记
            """
            firstLength = len(reList)
            # taListTable = copy.deepcopy(taList)
            taListEdit = copy.deepcopy(taList)

            for ta_x in range(firstLength):
                # 获取二维列表的第一个列表，即数据的第一行 [[11,800029,20],[11,800030,20],...]
                taLine_2 = taList[ta_x]  # [['10', '1', '1'], ['10', '2', '1']]
                reLine_2 = reList[ta_x]  # [['元宝', '1'], ['金币', '1']]
                secondLength = len(reLine_2)  # 默认取规划列长为默认的遍历长度

                # 判断每一行的列长是否不一致
                if len(reLine_2) != len(taLine_2):
                    offSet = len(reLine_2) - len(taLine_2)
                    if offSet > 0:
                        self.colorKey = 1
                        secondLength = len(taLine_2)
                        taListEdit[ta_x].append(self.MarkT(f'规划比基础表多出{offSet}列'))

                    else:
                        # 如果规划列长减去基础表列长为负数，则基础表列长比规划列长的长度大
                        offSet = abs(offSet)  # 取偏移量的绝对值
                        for offset_y in range(offSet):
                            # 为偏移量直接做标记
                            self.colorKey = 1
                            taListEdit[ta_x][-(offset_y + 1)] = self.MarkT(
                                f'[{",".join(taListEdit[ta_x][-(offset_y + 1)])}]')

                for ta_y in range(secondLength):
                    # 获取数据的第一行的第一列，即第一行的第一个reward列表 ['11', '20177', '20'],
                    taRewardItem_1 = taLine_2[ta_y]  # ['10', '1', '1']
                    reRewardItem_1 = reLine_2[ta_y]  # ['元宝', '1']

                    # 通过道具品类编码获取缓存数据
                    reReader = searcher.GetReader(dirPath, taRewardItem_1[0])
                    if not reReader:
                        _name = "【无缓存数据】"
                    else:
                        # 如果已经有缓存，则获取该ID的中文名称（该ID必须要有有中文名称）
                        _name = reReader.GetName(taRewardItem_1[1])
                        # 判断10和11的类型是否正确
                        if taRewardItem_1[0] == "10":
                            if not reReader.IsResource(taRewardItem_1[1]):
                                self.colorKey = 1
                                diffIndex.add(ta_x)
                                taListEdit[ta_x][ta_y][0] = self.MarkT(taRewardItem_1[0])
                        if taRewardItem_1[0] == "11":
                            if reReader.IsResource(taRewardItem_1[1]):
                                self.colorKey = 1
                                diffIndex.add(ta_x)
                                taListEdit[ta_x][ta_y][0] = self.MarkT(taRewardItem_1[0])

                    # 将规划中的道具和基础表中的道具中文名称进行比较
                    if _name != reRewardItem_1[0]:
                        self.colorKey = 1
                        # taListTable[ta_x][ta_y][1] = self.MarkT(f'{taRewardItem_1[1]},{_name}')
                        taListEdit[ta_x][ta_y][1] = self.MarkT(f'{taRewardItem_1[1]},{_name}')
                        diffIndex.add(ta_x)

                    # 将规划中的数量和基础表中的数量进行比较
                    if taRewardItem_1[2] != reRewardItem_1[1]:
                        self.colorKey = 1
                        # taListTable[ta_x][ta_y][2] = self.MarkT(f'{taRewardItem_1[2]}')
                        taListEdit[ta_x][ta_y][2] = self.MarkT(f'{taRewardItem_1[2]}')
                        diffIndex.add(ta_x)

            return taListEdit

        ##########################################################################################
        # 获取规划表框内容数据解析后的结果
        reRewards, reCosts = self.GetSAE(self.SResourceEdit, 0)
        # 获取基础表框内容数据解析后的结果
        taRewards, taCosts, allNumbers = self.GetSAE(self.STargetEdit, 1)

        _diffInfo = []
        diffIndex = set()
        # 读取基础表输入框中涉及的类型表格和读取结果results
        results = searcher.SendOrders(allNumbers)

        if results:
            # 展示错误信息提示框并返回，不往下执行
            self.openDialog.ShowMessage(results)
            return _diffInfo, diffIndex

        # 规划和基础表内容比对 ------------------------------------------------
        taRewardsEdit = CheckContents(reRewards, taRewards)  # 比对奖励内容是否一致
        length = len(taRewardsEdit)
        if self.SCostsComboBox:  # 如果有兑换消耗
            taCostsEdit = CheckContents(reCosts, taCosts)  # 比对消耗是否一致
            for x in range(length):
                if self.taTitleDic["rewards"] < self.taTitleDic["costs"]:
                    taRewardsEdit[x].append(taCostsEdit[x])
                else:
                    taRewardsEdit[x].insert(0, taCostsEdit[x])

        for x in range(length):
            self.taAllInfo.append(taRewardsEdit[x])
            self.reAllInfo.append(reRewards[x])
        return diffIndex

    def CheckDataText(self):
        """
        验证规划和基础表输入格式是否正确\n
        :return: 正确返回True
        """

        def CheckRe(lineList):
            """
            检查规划输入格式是否正确\n
            :param lineList: 规划字符串行列表
            """
            # 提取行头，并移除列表行头
            title = lineList.pop(0)

            # 1.通过空格将行头进行分割，获取列表长度，列表长度最短不可少于2
            myTitle = title.split()
            titleLength = len(myTitle)
            titleKey = True

            if self.SCostsComboBox:
                if titleLength < 4:
                    info.append(
                        f'titleLength_Erro:【规划】 行头字段数量少于4:【{titleLength}】,字段至少包含 [道具/奖励：数量，消耗：数量]'
                    )
                    titleKey = False
            else:
                if titleLength < 2:
                    info.append(
                        f'titleLength_Erro:【规划】 行头字段数量少于2:【{titleLength}】,字段至少包含 [道具/奖励：数量]'
                    )
                    titleKey = False

            if not titleKey:
                return

            # 2.先判断行头是否有道具，数量，再判断道具和数量的个数是否一致（仅行头）
            t = 0
            c = 0
            h = 0
            for item in myTitle:
                if myRe_Reward in item:
                    t += 1
                if '消耗' in item:
                    h += 1
                if '数量' in item:
                    c += 1
            if t == 0:
                info.append(
                    f'titleLength_Erro:【规划】 缺少”道具/奖励“字段，字段至少包含 [道具/奖励：数量]'
                )
                titleKey = False
            if c == 0:
                info.append(
                    f'titleLength_Erro:【规划】 缺少”数量“字段，字段至少包含 [道具/奖励：数量]'
                )
                titleKey = False
            # 3.如果存在消耗，判断道具+消耗的个数是否与数量的个数一致（仅行头）
            if self.SCostsComboBox:
                if h == 0:
                    info.append(
                        f'titleLength_Erro:【规划】 缺少”消耗“字段，字段至少包含 [道具/奖励：数量，消耗：数量]'
                    )
                    titleKey = False
                else:
                    if (t + h) > c:
                        info.append(
                            f'titleLength_Erro:【规划】 ”数量“字段的个数不正确，字段必须成对 [道具/奖励：数量，消耗：数量]'
                        )
                        titleKey = False
            else:
                if t > c:
                    info.append(
                        f'titleLength_Erro:【规划】 ”数量“字段的个数不正确，字段必须成对 [道具/奖励：数量]'
                    )
                    titleKey = False

            if not titleKey:
                return

            x = 0
            for line in lineList:
                x = x + 1

                # 4.通过空格将行数据进行分割，获取列表长度，列表长度最短不可少于2
                myText = line.split()
                lineLength = len(myText)
                if lineLength < 2:
                    info.append(
                        f'length_Erro:【规划】第{x}行 字段数量少于2:【{lineLength}】'
                    )
                # 5.判断每行的长度是否一致，如果不一致，最长不可超过行头长度，如果有消耗，最短不可少于4
                if titleLength < lineLength:
                    info.append(
                        f'length_Erro:【规划】第{x}行 字段数量【{lineLength}】大于行头字段数量【{titleLength}】'
                    )
                if self.SCostsComboBox:
                    if lineLength < 4:
                        info.append(
                            f'titleLength_Erro:【规划】第{x}行 字段数量小于4：【{lineLength}】'
                        )
                # 6.判断是否存在特殊符号
                fuHaoKey = False
                fuHaoList = []
                for myitem in myText:
                    zhongWenList = re.findall(zhongWen, myitem)
                    if not zhongWenList:
                        teSuFuHaoList = re.findall(teSuFuHao1, myitem)
                        if teSuFuHaoList:
                            fuHaoKey = True
                            fuHaoList.append(''.join(teSuFuHaoList))
                if fuHaoKey:
                    info.append(
                        f'fuHao_Erro:【规划】第{x}行 存在特殊符号【{"".join(fuHaoList)}】,请检查'
                    )

                # 7.判断是否存在小数
                myCount = []
                fuDianShuList = []
                for tRewards in self.reTitleDic['rewards']:
                    if tRewards:
                        myCount.append(tRewards[1])
                if self.SCostsComboBox:
                    for tCosts in self.reTitleDic['costs']:
                        if tCosts:
                            myCount.append(tCosts[1])
                if myCount:
                    for myIndex in myCount:
                        if len(myText) > myIndex:
                            fuDianShuTempList = re.findall(fuDianShu, myText[myIndex])
                            if fuDianShuTempList:
                                fuDianShuList.append(''.join(fuDianShuTempList))
                if fuDianShuList:
                    info.append(
                        f'fuDianShu_Erro:【规划】第{x}行 数量字段存在小数:【{"".join(fuDianShuList)}】'
                    )

        def checkTa(lineList):
            """
            检查基础表输入格式是否正确\n
            :param lineList: 基础表字符串行列表
            """

            # 提取行头，并移除列表行头
            title = lineList.pop(0)

            # 获取行头 rewards和costs下标
            if 'rewards' in self.taTitleDic:
                rewardsIndex = self.taTitleDic['rewards']
            else:
                info.append(f'title_Erro:【基础表】 缺少”rewards“字段')
                return

            costsIndex = None
            if self.SCostsComboBox:
                if 'costs' in self.taTitleDic:
                    costsIndex = self.taTitleDic['costs']
                else:
                    info.append(
                        f'title_Erro:【基础表】 缺少”costs“字段'
                    )
                    return

                    # 1.通过空格将行头进行分割，获取列表长度，列表长度最短不可少于1
            myTitle = title.split()
            titleLength = len(myTitle)
            if titleLength < 1:
                info.append(
                    f'titleLength_Erro:【基础表】 字段数量错误:【{titleLength}】,字段至少包含 [rewards]'
                )
                return
            # 如过勾选了消耗，字段数量不可少于2
            if self.SCostsComboBox:
                if titleLength < 2:
                    info.append(
                        f'titleLength_Erro:【基础表】 字段数量少于2:【{titleLength}】,字段至少包含 [rewards，costs]'
                    )
                    return
            # 2.先判断行头是否有道具，数量，再判断道具和数量的个数是否一致（仅行头）
            t = 0
            h = 0
            for item in myTitle:
                if myTa_Reward in item:
                    t += 1
                if 'costs' in item:
                    h += 1
            if t == 0:
                info.append(
                    f'title_Erro:【基础表】 缺少”rewards“字段'
                )
            # 如果存在消耗，判断道具+消耗的个数是否与数量的个数一致（仅行头）
            if self.SCostsComboBox:
                if h == 0:
                    info.append(
                        f'title_Erro:【基础表】 缺少”costs“字段'
                    )

            x = 0
            for line in lineList:
                x = x + 1
                lengthKey = True
                # 3.通过空格将行数据进行分割，获取列表长度，列表长度最短不可少于1
                myText = line.split()
                lineLength = len(myText)
                if lineLength < 1:
                    info.append(
                        f'length_Erro:【基础表】第{x}行 字段数量少于1:【{lineLength}】'
                    )
                    lengthKey = False
                # 4.判断每行的长度是否一致，如果不一致，最长不可超过行头长度，如果有消耗，最短不可少于2
                if titleLength < lineLength:
                    info.append(
                        f'length_Erro:【基础表】第{x}行 字段数量【{lineLength}】大于行头字段数量【{titleLength}】'
                    )
                if self.SCostsComboBox:
                    if lineLength < 2:
                        info.append(
                            f'titleLength_Erro:【基础表】第{x}行 字段数量小于2：【{lineLength}】'
                        )
                        lengthKey = False

                # 5.判断中括号是否成对
                liebiaofu1list = re.findall(lieBiaoFu1, line)
                liebiaofu2list = re.findall(lieBiaoFu2, line)
                if len(liebiaofu1list) != len(liebiaofu2list):
                    info.append(f'kuoHao_Erro:【基础表】第{x}行 中括号” [ ] “对数不正确！')

                # 6.判断是否存在空格
                konggeList = []
                for myItem in myText:
                    if ' ' in myItem:
                        konggeList.append(myItem)
                if konggeList:
                    info.append(f'kongGe_Erro:【基础表】第{x}行 列表:{"".join(konggeList)} 存在空格！')

                if lengthKey:
                    if len(myText) < rewardsIndex + 1:
                        info.append(
                            f'rewardsIndex_Erro:【基础表】第{x}行 rewards列表不存在，请检查头部字段位置是否与下方列表位置一致！'
                        )
                        return
                    else:
                        if self.SCostsComboBox:
                            if len(myText) < costsIndex + 1:
                                info.append(
                                    f'costsIndex_Erro:【基础表】第{x}行 costs列表不存在，请检查头部字段位置是否与下方列表位置一致！'
                                )
                                return

                    # 7.判断是否存在非数字
                    feiShuZiList = []
                    rewardList = re.findall(reward, myText[rewardsIndex])
                    if rewardList:
                        for rewardItem in rewardList:
                            feiShuZiTemp = re.findall(feiShuZi, rewardItem)
                            if feiShuZiTemp:
                                feiShuZiList.append(''.join(feiShuZiTemp))
                    if feiShuZiList:
                        info.append(
                            f'feiShuZi_Erro:【基础表】第{x}行 rewards列表{myText[rewardsIndex]}存在非数字内容【{"".join(feiShuZiList)}】'
                        )

                    if self.SCostsComboBox:
                        feiShuZiList.clear()
                        costsList = re.findall(reward, myText[costsIndex])
                        if costsList:
                            for costsItem in costsList:
                                feiShuZiTemp = re.findall(feiShuZi, costsItem)
                                if feiShuZiTemp:
                                    feiShuZiList.append(''.join(feiShuZiTemp))
                        if feiShuZiList:
                            info.append(
                                f'feiShuZi_Erro:【基础表】第{x}行 costs列表{myText[costsIndex]}存在非数字内容【{"".join(feiShuZiList)}】'
                            )

                    # 8.判断是否存在小数
                    fuDianShuKey = True
                    fuDianShuList = re.findall(fuDianShu, myText[rewardsIndex])
                    if fuDianShuList:
                        info.append(
                            f'fuDianShu_Erro:【基础表】第{x}行 rewards 列表中存在小数:【{"".join(fuDianShuList)}】'
                        )
                        fuDianShuKey = False
                    if self.SCostsComboBox:
                        fuDianShuList = re.findall(fuDianShu, myText[costsIndex])
                        if fuDianShuList:
                            info.append(
                                f'fuDianShu_Erro:【基础表】第{x}行 costs 列表中存在小数:【{"".join(fuDianShuList)}】'
                            )
                            fuDianShuKey = False

                    # 9.判断是否存在特殊符号
                    fuHaoList = []
                    fuHaoKey = True
                    teSuFuHaoTemp = teSuFuHao1
                    if fuDianShuKey:
                        teSuFuHaoTemp = teSuFuHao2

                    for myitem in myText:
                        # 判断是否存在中文，如果存在中文，允许有特殊符号
                        zhongWenList = re.findall(zhongWen, myitem)
                        if not zhongWenList:
                            teSuFuHaoList = re.findall(teSuFuHaoTemp, myitem)
                            if teSuFuHaoList:
                                fuHaoKey = False
                                fuHaoList.append(''.join(teSuFuHaoList))
                    if not fuHaoKey:
                        info.append(f'fuHao_Erro:【基础表】第{x}行 存在特殊符号【{"".join(fuHaoList)}】,请检查')

                    if fuDianShuKey and fuHaoKey:
                        # 10.提取出逗号检查逗号数量是否正确，逗号的数量 = length * 2 + length - 1
                        douHaoList = re.findall(douHao, myText[rewardsIndex])
                        valueLength = len(re.findall(reward, myText[rewardsIndex]))
                        if (valueLength * 2 + valueLength - 1) != len(douHaoList):
                            info.append(f'douHaoErro:【基础表】第{x}行 rewards列表的 "," 数量【{len(douHaoList)}】不正确')
                        if self.SCostsComboBox:
                            douHaoList = re.findall(douHao, myText[costsIndex])
                            valueLength = len(re.findall(reward, myText[costsIndex]))
                            if (valueLength * 2 + valueLength - 1) != len(douHaoList):
                                info.append(f'douHaoErro:【基础表】第{x}行 costs列表的 "," 数量【{len(douHaoList)}】不正确')

        def reTitleIndex(_str):
            """
            获取规划字段下标\n
            :param _str: 规划行头
            :return: 返回字典{rewards:[[道具/奖励下标，数量下标],...],costs:[[消耗下标，数量下标],...]}
            """
            strList = _str.split()
            rewardTitle = []
            costTitle = []
            titleIndexDic = {'rewards': rewardTitle, 'costs': costTitle}
            length = len(strList)
            myReward = None

            for source_reward in source_rewards:
                if source_reward in _str:
                    if myReward:
                        if myReward != source_reward:
                            info.append(f"规划抬头中存在多个代表道具的字段【{myReward}】【{source_reward}】")
                    else:
                        myReward = source_reward

            for x in range(length):
                if myReward in strList[x]:
                    for y in range(length):
                        if y > x:
                            if "数量" in strList[y]:
                                titleIndexDic['rewards'].append([x, y])
                                break
                            else:
                                if y == length:
                                    titleIndexDic['rewards'].append([x, -1])
                if self.SCostsComboBox:
                    if "消耗" in strList[x]:
                        for y in range(length):
                            if y > x:
                                if "数量" in strList[y]:
                                    titleIndexDic['costs'].append([x, y])
                                    break
                                else:
                                    if y == length:
                                        titleIndexDic['costs'].append([x, -1])

            if not myReward:
                info.append("规划中无表示道具的相关字段")

            return titleIndexDic, myReward

        def taTitleIndex(_str):
            """
            获取基础表 costs，rewards 的位置\n
            :param _str:基础表行头
            :return:返回字典{'rewards': 下标, 'costs': 下标}
            """
            strList = _str.split()
            titleIndexDic = {}
            myReward = None
            for x in range(len(strList)):
                for target_reward in target_rewards:
                    if target_reward in strList[x]:
                        titleIndexDic['rewards'] = x
                        myReward = target_reward
                        break
            for x in range(len(strList)):
                if 'costs' in strList[x]:
                    titleIndexDic['costs'] = x
                    break
            if not myReward:
                info.append("基础表中无表示rewards的相关字段")

            return titleIndexDic, myReward

        ################################################################
        douHao = ","  # 匹配逗号
        lieBiaoFu1 = '\['  # 匹配左列表符号
        lieBiaoFu2 = '\]'  # 匹配右列表符号
        fuDianShu = '(-?\d+\.\d+)'  # 匹配浮点数
        reward = '-?\d+,-?\d+,-?\d+'  # 匹配reward列表（不带[]符号）
        # rewardspa = '-?\d+,-?\d+ -?\d+'  # 匹配规划reward源格式列表（不带[]符号）
        # rewardlis = '\[-?\d*,-?\d*,-?\d*\]'  # 匹配reward列表（带[]符号）
        # rewardPT1 = '-?\d+,-?\d+ -?\d+\s\d+\s\d+'  # 规划输入框匹配包含折扣和限购
        # rewardPT2 = '\]\]\s\d+\s\d+'  # 基础表输入框匹配包含折扣和限购
        zhongWen = '[\u4e00-\u9fa5]'
        feiShuZi = '[^0-9,]+'
        teSuFuHao1 = '[=?!@#$%^&*()_+:"<>/\\`~——，。、《》？；’：“【】、{}|·！￥…（）-]'  # 匹配各种标点符号
        teSuFuHao2 = '[=.?!@#$%^&*()_+:"<>/\\`~——，。、《》？；’：“【】、{}|·！￥…（）-]'  # 匹配各种标点符号(包括.)
        info = []  # 初始化信息收集列表
        reText = self.SResourceEdit.strip()  # 活动查询-规划输入框文本
        taText = self.STargetEdit.strip()  # 活动查询-基础表输入框文本
        source_rewards = self.config.parametersConfigJson['source_rewards']
        target_rewards = self.config.parametersConfigJson['target_rewards']
        myRe_Reward = None
        myTa_Reward = None

        # 将字符串分割成行列表
        taDataList = taText.splitlines()
        # 将带行头字段的列表复制一份，用来后面进行格式校验时使用
        taCheckList = copy.deepcopy(taDataList)

        # 拿出第一行，获取字段位置，规划返回字典，基础表返回布尔值
        self.taTitleDic, myTa_Reward = taTitleIndex(taDataList.pop(0))

        if reText:
            reDataList = reText.splitlines()
            reCheckList = copy.deepcopy(reDataList)
            self.reTitleDic, myRe_Reward = reTitleIndex(reDataList.pop(0))
            # 判断行数是否一致
            offset_x = len(reDataList) - len(taDataList)  # 获取长度差异值
            if offset_x != 0:  # 行数不一致时
                if offset_x > 0:  # 如果大于0说明比对源行数多
                    info.append(f'【规划】比 基础表 多 {abs(offset_x)} 行!')
                else:
                    info.append(f'【基础表】比 规划 多 {abs(offset_x)} 行!')
            CheckRe(reCheckList)  # 执行比对 源 格式自查

        checkTa(taCheckList)  # 执行比对 目标 格式自查

        if info:
            self.openDialog.ShowMessage('\n'.join(info))
            return False
        else:
            return True
